home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / POPCLI.C < prev    next >
Text File  |  1993-10-14  |  6KB  |  266 lines

  1. /*
  2.  *    POP2 Client routines.  Originally authored by Mike Stockett (WA7DYX).
  3.  *
  4.  *    Modified 12 May 1991 by Mark Edwards (WA6SMN) to use new timer
  5.  *    facilities in NOS0423.  Fixed type mismatches spotted by C++.
  6.  *    Modified 27 May 1990 by Allen Gwinn (N5CKP) for compatibility
  7.  *      with later releases (NOS0522).
  8.  *    Added into NOS by PA0GRI (and linted into "standard" C)
  9.  *
  10.  *    Some code culled from previous releases of SMTP.
  11.  *
  12.  *    Client routines for Simple Mail Transfer Protocol ala RFC821
  13.  *    A.D. Barksdale Garbee II, aka Bdale, N3EUA
  14.  *    Copyright 1986 Bdale Garbee, All Rights Reserved.
  15.  *    Permission granted for non-commercial copying and use, provided
  16.  *      this notice is retained.
  17.  *     Modified 14 June 1987 by P. Karn for symbolic target addresses,
  18.  *      also rebuilt locking mechanism
  19.  *    Copyright 1987 1988 David Trulli, All Rights Reserved.
  20.  *    Permission granted for non-commercial copying and use, provided
  21.  *    this notice is retained.
  22.  */
  23. #include <stdio.h>
  24. #include <conio.h>
  25. #include "global.h"
  26. #include "config.h"
  27. #ifdef POP
  28. #include "cmdparse.h"
  29. #include "socket.h"
  30. #include "netuser.h"
  31. #include "files.h"
  32. #include "smtp.h"
  33. #include "pop.h"
  34. #include "clients.h"
  35.  
  36.  
  37. static int16 Popquiet = 0;
  38.  
  39. static void
  40. poppoll(int unused,void *cb1,void *p)
  41. {
  42.     struct sockaddr_in fsocket;
  43.     char *cp, fname[MAXPATH];
  44.     int32 msgid = 0;
  45.     struct popcli *ccb;
  46.     struct Server *np = (struct Server *)cb1;
  47.  
  48.     fsocket.sin_family = AF_INET;
  49.     fsocket.sin_addr.s_addr = np->address;
  50.     fsocket.sin_port = IPPORT_POP;
  51.  
  52.     np->busy = TRUE;
  53.  
  54.     ccb = mxallocw(sizeof(struct popcli));
  55.     ccb->buf = mxallocw(BUF_LEN);
  56.  
  57.     cli_login(IPPORT_POP,(void *)np);
  58.  
  59.     if(np->arg1 == NULLCHAR
  60.       || np->arg2 == NULLCHAR
  61.       || np->arg3 == NULLCHAR) {
  62.         tputs("Missing entries in structure\n");
  63.         goto quit;
  64.     }
  65.  
  66.     if((ccb->socket = socket(AF_INET,SOCK_STREAM,0)) == -1) {
  67.         goto quit;
  68.     }
  69.     sockmode(ccb->socket,SOCK_ASCII);
  70.  
  71.     if(connect(ccb->socket,(char *)&fsocket,SOCKSIZE) != -1) {
  72.         log(ccb->socket,9983,"POP  connect");
  73.         ccb->state = CALL;
  74.  
  75.         for(; ; ) {
  76. loop:
  77.             if(ccb->state == EXIT) {
  78.                 usputs(ccb->socket,"QUIT\n");
  79.                 break;
  80.             }
  81.             if(recvline(ccb->socket,ccb->buf,BUF_LEN) == -1) {
  82.                 break;
  83.             }
  84.             rip(ccb->buf);
  85.  
  86.             switch(ccb->state) {
  87.             case CALL:
  88.                 if(strncmp(ccb->buf,"+ POP2 ",7) == 0) {
  89.                     usprintf(ccb->socket,"HELO %s %s\n",np->arg2,np->arg3);
  90.                     ccb->state = NMBR;
  91.                 } else {
  92.                     ccb->state = EXIT;
  93.                 }
  94.                 goto loop;
  95.             case NMBR:
  96.                 switch(*ccb->buf) {
  97.                 case '#':
  98.                     usputs(ccb->socket,"READ\n");
  99.                     ccb->state = SIZE;
  100.                     break;
  101.                 default:
  102. /*                case '+':    */
  103.                     /* If there is no mail (the only time we get a "+"
  104.                      * response back at this stage of the game),
  105.                      * then just close out the connection, because
  106.                      * there is nothing more to do!! */
  107.                     ccb->state = EXIT;
  108.                 }
  109.                 goto loop;
  110.             case SIZE:
  111.                 if(*ccb->buf == '=') {
  112.                     if((ccb->msg_len = atol(&(ccb->buf[1]))) > 0) {
  113.                         msgid = get_msgid();
  114.  
  115.                         sprintf(fname,"%s/%ld.txt",Mailqdir,msgid);
  116.                         if((ccb->fd = Fopen(fname,WRITE_TEXT,0,1)) != NULLFILE) {
  117.                             usputs(ccb->socket,"RETR\n");
  118.                             ccb->state = XFER;
  119.                             goto loop;
  120.                         }
  121.                     }
  122.                 }
  123.                 ccb->state = EXIT;
  124.                 goto loop;
  125.             case XFER:
  126.                 fprintf(ccb->fd,"%s\n",ccb->buf);
  127.  
  128.                 /* Add CRLF */
  129.                 if((ccb->msg_len -= (long)(strlen(ccb->buf)+2)) > 0) {
  130.                     goto loop;
  131.                 }
  132.                 /* All done, so do local cleanup */
  133.                 Fclose(ccb->fd);
  134.  
  135.                 sprintf(fname,"%s/%ld.wrk",Mailqdir,msgid);
  136.                 if((ccb->fd = Fopen(fname,WRITE_TEXT,0,1)) != NULLFILE) {
  137.                     fprintf(ccb->fd,"%s\n%s\n\%s\n",Hostname,np->name,np->arg1);
  138.                     Fclose(ccb->fd);
  139.                 }
  140.                 usputs(ccb->socket,"ACKD\n");
  141.  
  142.                 switch(Popquiet) {
  143.                 case 0:
  144.                     putch(7);
  145.                 case 1:
  146.                     /* timestamp by dc3sn */
  147.                     tprintf("POP: new mail for %s from %s at %s\n",
  148.                         np->arg1,np->name,timestr(currtime));
  149.                     break;
  150.                 case 3:
  151.                     log(-1,IPPORT_POP,"POP new mail from %s",np->name);
  152.                     break;
  153.                 }
  154.                 ccb->state = SIZE;
  155.             default:
  156.                 goto loop;
  157.             }
  158.         }
  159.     }
  160.     if(ccb->fd != NULLFILE) {
  161.         Fclose(ccb->fd);
  162.     }
  163.     if((cp = sockerr(ccb->socket)) == NULLCHAR) {
  164.         cp = "EOF";
  165.     }
  166.     log(ccb->socket,9983,"POP  closed %s",cp);
  167.  
  168.     recvline(ccb->socket,ccb->buf,BUF_LEN);
  169.     close_s(ccb->socket);
  170.  
  171. quit:
  172.     xfree(ccb->buf);
  173.     xfree(ccb);
  174.     np->busy = FALSE;
  175.     return;
  176. }
  177.  
  178. /* --------------------------- Popcli subcmds ----------------------------- */
  179.  
  180.  
  181. static int
  182. dopopadds(int argc,char **argv,void *p)
  183. {
  184.     struct Server *np;
  185.  
  186.     if((np = addserver(IPPORT_POP,argv[1])) == NULLSERVER) {
  187.         return -1;
  188.     }
  189.     if(argc == 2) {
  190.         if(!(cli_login(IPPORT_POP,(void *)np))) {
  191.             tputs("No userdata in file\n");
  192.         }
  193.         return 0;
  194.     }
  195.     if(argc != 5) {
  196.         tputs("Syntax error\n");
  197.         return -1;
  198.     }
  199.     np->arg1 = strxdup(argv[2]);
  200.     np->arg2 = strxdup(argv[3]);
  201.     np->arg3 = strxdup(argv[4]);
  202.  
  203.     return 0;
  204. }
  205.  
  206. /* drops servers from list */
  207. static int
  208. dopopdrops(int argc,char **argv,void *p)
  209. {
  210.     dropserver(IPPORT_POP,argv[1]);
  211.     return 0;
  212. }
  213.  
  214. static int
  215. popkick(int argc,char **argv,void *p)
  216. {
  217.     int32 addr = 0;
  218.     struct Server *np;
  219.  
  220.     if(argc > 1 && (addr = resolve(argv[1])) == 0){
  221.         tprintf(Badhost,argv[1]);
  222.         return 1;
  223.     }
  224.     for(np = Server; np != NULLSERVER; np = np->next) {
  225.         if(np->protocol != IPPORT_POP
  226.           || np->busy
  227.           || (addr && (np->address != addr))) {
  228.             continue;
  229.         } else {
  230.             newproc("POP Client",1024,poppoll,0,(void *)np,0,0);
  231.         }
  232.     }
  233.     return 0;
  234. }
  235.  
  236. static int
  237. dopoplists(int argc,char **argv,void *p)
  238. {
  239.     static char *a = "Mailbox   User";
  240.  
  241.     listserver(IPPORT_POP,argv[1],a);
  242.     return 0;
  243. }
  244.  
  245. static int
  246. doquiet(int argc,char **argv,void *p)
  247. {
  248.     return setintrc(&Popquiet,"POP quiet",argc,argv,0,3);
  249. }
  250.  
  251. int
  252. dopop(int argc,char **argv,void *p)
  253. {
  254.     struct cmds Popcmds[] = {
  255.         {"add",            dopopadds,  0,    2,    "pop add <server> [<mailbox> <user> <pass>]"},
  256.         {"drop",        dopopdrops,    0,    2,    "pop drop <server>"},
  257.         {"list",        dopoplists,    0,    0,    NULLCHAR},
  258.         {"kick",        popkick,    0,    0,    NULLCHAR},
  259.         {"quiet",        doquiet,    0,    0,    NULLCHAR},
  260.         NULLCHAR,
  261.     };
  262.     return subcmd(Popcmds,argc,argv,p);
  263. }
  264.  
  265. #endif /* POP */
  266.